package com.game.logic.messages;

import com.game.framework.common.error.EventExecutorGroup;
import com.game.framework.mqsystem.event.GameEventContext;
import com.game.logic.channel.ServerChannelGroup;
import com.game.logic.config.GameServerConfig;
import com.game.logic.service.ReceiveConsumeMessageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer;
import org.springframework.context.ApplicationContext;

import java.util.function.Consumer;

@Slf4j
public class GameMessageServerContext {

	private ApplicationContext applicationContext;
	private EventExecutorGroup logicGroup;
	private EventExecutorGroup dbGroup;
	private ServerChannelGroup serverChannelGroup;
	private GameServerConfig serverConfig;
	private GameEventContext gameEventContext;
	private ReceiveConsumeMessageService receiveConsumeMessageService;
	public GameMessageServerContext(ApplicationContext context) {
		this.applicationContext = context;
		this.serverConfig = applicationContext.getBean(GameServerConfig.class);
		int logicThreads = this.serverConfig.getLogicThreadCount();
		int dbThreads = this.serverConfig.getDbThreads();
		if (logicThreads <= 0) {
			logicThreads = Runtime.getRuntime().availableProcessors();
		}
		if (dbThreads <= 0) {
			dbThreads = Runtime.getRuntime().availableProcessors() * 2;
		}
		this.logicGroup = new EventExecutorGroup(logicThreads,"GameLogicExecutor");
		this.dbGroup = new EventExecutorGroup(dbThreads,"DB-Executor");
		this.serverChannelGroup = new ServerChannelGroup(this.logicGroup, this.applicationContext);
		// 启动事件系统
		this.gameEventContext = new GameEventContext(serverConfig.getLocalServerId(), applicationContext);
		// 启动事件系统
		if(this.receiveConsumeMessageService ==null) {
			this.receiveConsumeMessageService = new ReceiveConsumeMessageService();
		}
		String gatewayMessageTopic = this.receiveConsumeMessageService.getTopic();
		foreachRocketMQListenerContainer(container -> {
			if (container.getTopic().equals(gatewayMessageTopic)) {
				if (this.serverConfig.getGatewayConsumeThreads() > 0) {
					container.getConsumer().updateCorePoolSize(this.serverConfig.getGatewayConsumeThreads());
					int coreSize = container.getConsumer().getDefaultMQPushConsumerImpl().getConsumeMessageService().getCorePoolSize();
					log.info("处理网关消息的消费者线程池被修改为：{} 个", coreSize);
				} else {
					int coreSize = container.getConsumer().getDefaultMQPushConsumerImpl().getConsumeMessageService().getCorePoolSize();
					log.info("处理网关消息的消费者线程池核心数量：{} 个", coreSize);
				}
			}
		});
	}

	private void foreachRocketMQListenerContainer(Consumer<DefaultRocketMQListenerContainer> consumer) {
		String[] names = applicationContext.getBeanNamesForType(DefaultRocketMQListenerContainer.class);
		if (names.length == 0) {
			log.info("未找到RocketMQ的消费者监听容器");
			return;
		}
		DefaultRocketMQListenerContainer rocketMQListenerContainer = null;
		for (String name : names) {
			rocketMQListenerContainer = (DefaultRocketMQListenerContainer) applicationContext.getBean(name);
			consumer.accept(rocketMQListenerContainer);
		}
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setApplicationContext(ApplicationContext context) {
		this.applicationContext = context;
	}

	public EventExecutorGroup getLogicGroup() {
		return logicGroup;
	}

	public void setLogicGroup(EventExecutorGroup logicGroup) {
		this.logicGroup = logicGroup;
	}

	public EventExecutorGroup getDbGroup() {
		return dbGroup;
	}

	public void setDbGroup(EventExecutorGroup dbGroup) {
		this.dbGroup = dbGroup;
	}

	public ServerChannelGroup getServerChannelGroup() {
		return serverChannelGroup;
	}

	public void setServerChannelGroup(ServerChannelGroup serverChannelGroup) {
		this.serverChannelGroup = serverChannelGroup;
	}

	public GameServerConfig getServerConfig() {
		return serverConfig;
	}

	public void setServerConfig(GameServerConfig serverConfig) {
		this.serverConfig = serverConfig;
	}

	public GameEventContext getGameEventContext() {
		return gameEventContext;
	}

	public void setGameEventContext(GameEventContext gameEventContext) {
		this.gameEventContext = gameEventContext;
	}

	public ReceiveConsumeMessageService getReceiveConsumeMessageService() {
		return receiveConsumeMessageService;
	}

	public void setReceiveConsumeMessageService(ReceiveConsumeMessageService receiveConsumeMessageService) {
		this.receiveConsumeMessageService = receiveConsumeMessageService;
	}

}
